home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / smaltalk / manchest.lha / MANCHESTER / usenet / st80_pre4 / conc.st < prev    next >
Text File  |  1993-07-24  |  7KB  |  299 lines

  1. "    NAME        conc
  2.     AUTHOR        mip@massormetrix.ida.liu.se (Mikael Patel)
  3.     FUNCTION    Concurrent Programming Classes
  4.     ST-VERSION    ?
  5.     PREREQUISITES    
  6.     CONFLICTS
  7.     DISTRIBUTION    world
  8.     VERSION        1
  9.     DATE    6 Oct 1989
  10. SUMMARY Implements monitors, conditions, shared objects, and unbounded buffers.
  11. "
  12.  
  13. '
  14. Newsgroups: comp.lang.smalltalk
  15. Subject: Concurrent Programming Classes
  16. Keywords: Examples, Concurrent Programming in OOP
  17. Message-ID: <1368@massormetrix.ida.liu.se>
  18. Organization: Dept of Comp and Info Science, Univ of Linkoping, Sweden
  19.  
  20. Hi, Smalltalkers out there, here are some more examples. This time 
  21. some of the abstractions that are used in concurrent programming:
  22.  
  23. * Monitor: methods are executed under mutual exculusion
  24. * Condition: synchronization variables within a monitor
  25. * SharedObject: multiple readers or one writer
  26. * UnboundedBuffer: classical monitor example
  27.  
  28. The implementation follows more or less directly the specification
  29. found in books like M.Ben-Ari, Principles of Concurrent Programming,
  30. Prentice-Hall, 1982.
  31.  
  32. They are excellent for demonstrating problems with combinding object-
  33. oriented programming with concurrency. Especially that monitors can not
  34. be inherited (super class) and monitor-to-monitor messages give dead-locks.
  35.  
  36. Mikael R.K. Patel
  37. Researcher and Lecturer
  38. Computer Aided Design Laboratory
  39. Department of Computer and Information Science
  40. Linkoping University, S-581 83  LINKOPING, SWEDEN
  41.  
  42. Phone: +46 13281821
  43. Telex: 8155076 LIUIDA S            Telefax: +46 13142231
  44. Internet: mip@ida.liu.se        UUCP: ...!!sunic!!liuida!!mip
  45. Bitnet: MIP@SELIUIDA            SUNET: LIUIDA::MIP
  46. '
  47.  
  48. Object subclass: #Condition
  49.     instanceVariableNames: 'monitor synchronize waiting '
  50.     classVariableNames: ''
  51.     poolDictionaries: ''
  52.     category: 'Concurrent-Programming'!
  53.  
  54.  
  55. !Condition methodsFor: 'synchronizing'!
  56.  
  57. signal
  58.     "Check if there are waiting processes. Signal and wait for monitor 
  59.     again "
  60.  
  61.     waiting > 0
  62.         ifTrue: 
  63.             [synchronize signal.
  64.             monitor waitForSignal]!
  65.  
  66. wait
  67.     "Wait for condition signal. Check if there are waiting signalers"
  68.  
  69.     waiting _ waiting + 1.
  70.     monitor waitingForSignal > 0
  71.         ifTrue: [monitor signalWaitingForSignal]
  72.         ifFalse: [monitor signalMutualExculsion].
  73.     synchronize wait.
  74.     waiting _ waiting - 1.! !
  75.  
  76. !Condition methodsFor: 'initialization'!
  77.  
  78. initiate: aMonitor 
  79.     "Initiate a newly create condition in the given monitor environment"
  80.  
  81.     waiting _ 0.
  82.     monitor _ aMonitor.
  83.     synchronize _ Semaphore new! !
  84.  
  85. !Condition methodsFor: 'accessing'!
  86.  
  87. waiting
  88.     "Return number of waiting processes"
  89.  
  90.     ^waiting! !
  91. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  92.  
  93. Condition class
  94.     instanceVariableNames: ''!
  95.  
  96.  
  97. !Condition class methodsFor: 'instance creation'!
  98.  
  99. in: aMonitor 
  100.     "Create a new conditon in the given monitor"
  101.  
  102.     ^super new initiate: aMonitor! !
  103.  
  104. Object subclass: #Monitor
  105.     instanceVariableNames: 'mutex urgent '
  106.     classVariableNames: ''
  107.     poolDictionaries: ''
  108.     category: 'Concurrent-Programming'!
  109.  
  110.  
  111. !Monitor methodsFor: 'initialization'!
  112.  
  113. initiate
  114.     " Create a new abstract monitor with mutual exclusion and 
  115.     synchronization condition"
  116.  
  117.     mutex _ Semaphore forMutualExclusion.
  118.     urgent _ Condition in: self! !
  119.  
  120. !Monitor methodsFor: 'method-protocol'!
  121.  
  122. enter
  123.     "Pre-protocol to a monitor method"
  124.  
  125.     mutex wait!
  126.  
  127. exit
  128.     "Post-protocol for monitor methods"
  129.  
  130.     urgent waiting > 0
  131.         ifTrue: [urgent signal]
  132.         ifFalse: [mutex signal]! !
  133.  
  134. !Monitor methodsFor: 'synchronization'!
  135.  
  136. signalMutualExculsion
  137.     "External signaling for mutual execulsion"
  138.  
  139.     mutex signal!
  140.  
  141. signalWaitingForSignal
  142.     "Signal waiting process which has passed on control"
  143.  
  144.     urgent signal!
  145.  
  146. waitForSignal
  147.     "Wait for signal when activated process waiting for signal"
  148.  
  149.     urgent wait!
  150.  
  151. waitingForSignal
  152.     "Returns number of waiting signalers"
  153.  
  154.     ^urgent waiting! !
  155. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  156.  
  157. Monitor class
  158.     instanceVariableNames: ''!
  159.  
  160.  
  161. !Monitor class methodsFor: 'instance creation'!
  162.  
  163. new
  164.     "Create a new instance of the monitor and initiate it"
  165.  
  166.     ^super new initiate! !
  167.  
  168. Monitor subclass: #SharedObject
  169.     instanceVariableNames: 'readers writers okToRead okToWrite '
  170.     classVariableNames: ''
  171.     poolDictionaries: ''
  172.     category: 'Concurrent-Programming'!
  173.  
  174.  
  175. !SharedObject methodsFor: 'transactions'!
  176.  
  177. releaseAfterRead
  178.     "Release the shared object after reading"
  179.  
  180.     self enter.
  181.     readers _ readers - 1.
  182.     readers = 0 ifTrue: [okToWrite signal].
  183.     self exit!
  184.  
  185. releaseAfterWrite
  186.     "Release the shared object after writing"
  187.  
  188.     self enter.
  189.     writers _ false.
  190.     okToRead signal.
  191.     self exit!
  192.  
  193. siezeToRead
  194.     "Seize the shared object for reading. Uses cascaded wakeup of waiting readers"
  195.  
  196.     self enter.
  197.     writers ifTrue: [okToRead wait. okToRead signal].
  198.     readers _ readers + 1.
  199.     self exit!
  200.  
  201. siezeToWrite
  202.     "Seize the shared object for writing"
  203.  
  204.     self enter.
  205.     (readers > 0 or: [writers]) ifTrue: [okToWrite wait].
  206.     writers _ true.
  207.     self exit! !
  208.  
  209. !SharedObject methodsFor: 'initialization'!
  210.  
  211. initiate
  212.     "Initiate a shared object"
  213.  
  214.     super initiate.
  215.     readers _ 0.
  216.     writers _ false.
  217.     okToRead _ Condition in: self.
  218.     okToWrite _ Condition in: self.! !
  219.  
  220. !SharedObject methodsFor: 'private'!
  221.  
  222. testing
  223.  
  224.     S _ SharedObject new.
  225.     S inspect.
  226.     S siezeToRead.
  227.     S siezeToWrite.
  228.     S releaseAfterWrite.
  229.     S releaseAfterRead.! !
  230. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  231.  
  232. SharedObject class
  233.     instanceVariableNames: ''!
  234.  
  235.  
  236. !SharedObject class methodsFor: 'instance creation'!
  237.  
  238. new
  239.     "Create a new shared object instance and initiate it"
  240.  
  241.     ^super new initiate! !
  242.  
  243. Monitor subclass: #UnboundedBuffer
  244.     instanceVariableNames: 'items notEmpty '
  245.     classVariableNames: ''
  246.     poolDictionaries: ''
  247.     category: 'Concurrent-Programming'!
  248.  
  249.  
  250. !UnboundedBuffer methodsFor: 'initialization'!
  251.  
  252. initiate
  253.     "Initiate the monitor (super class) and the buffer and condition"
  254.  
  255.     super initiate.
  256.     items _ OrderedCollection new.
  257.     notEmpty _ Condition in: self.! !
  258.  
  259. !UnboundedBuffer methodsFor: 'private'!
  260.  
  261. testing
  262.     "A simple test of the unbounded buffer"
  263.  
  264.     B _  UnboundedBuffer new.
  265.     B append: 100.
  266.     B take.
  267.     B inspect.! !
  268.  
  269. !UnboundedBuffer methodsFor: 'transactions'!
  270.  
  271. append: anItem
  272.     "Append an item to the buffer"
  273.  
  274.     self enter.
  275.     items addLast: anItem.
  276.     self exit.!
  277.  
  278. take
  279.     "Take an item from the buffer if available else wait until not empty"
  280.  
  281.     | anItem |
  282.     self enter.
  283.     items isEmpty ifTrue: [notEmpty wait].
  284.     anItem _ items removeFirst.
  285.     self exit.
  286.     ^anItem! !
  287. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  288.  
  289. UnboundedBuffer class
  290.     instanceVariableNames: ''!
  291.  
  292.  
  293. !UnboundedBuffer class methodsFor: 'instance creation'!
  294.  
  295. new
  296.     "Create a new instance and initiate it"
  297.  
  298.     ^super new initiate! !
  299.